<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>深入理解DJL中的NDArray | 技术小馆</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            color: #333;
            line-height: 1.6;
        }
        h1, h2, h3, h4 {
            font-family: 'Noto Serif SC', serif;
            font-weight: 600;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        }
        .code-block {
            background-color: #2d3748;
            color: #f8fafc;
            border-radius: 0.5rem;
            overflow-x: auto;
        }
        .feature-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .mermaid-tooltip {
            background-color: white;
            border: 1px solid #e2e8f0;
            border-radius: 0.375rem;
            padding: 0.5rem;
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
            font-size: 0.875rem;
        }
        .footer-link:hover {
            color: #a0aec0;
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20 px-4 sm:px-6 lg:px-8">
        <div class="max-w-4xl mx-auto text-center">
            <div class="inline-block bg-white bg-opacity-20 rounded-full px-6 py-2 mb-6">
                <span class="text-sm font-semibold tracking-wider">DJL深度学习</span>
            </div>
            <h1 class="text-4xl md:text-5xl font-bold mb-6">深入理解DJL中的NDArray</h1>
            <p class="text-xl opacity-90 max-w-3xl mx-auto">N维数组：深度学习中的核心数据结构与运算单元</p>
            <div class="mt-10 flex justify-center">
                <div class="w-12 h-1 bg-purple-300 rounded-full"></div>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
        <!-- Introduction Section -->
        <section class="mb-16">
            <div class="flex items-center mb-8">
                <div class="w-8 h-8 bg-purple-600 rounded-full flex items-center justify-center text-white mr-4">
                    <i class="fas fa-cube"></i>
                </div>
                <h2 class="text-3xl font-bold">什么是DJL中的NDArray？</h2>
            </div>
            
            <div class="bg-white rounded-xl shadow-md p-8 mb-8">
                <p class="text-lg mb-6">
                    在 <strong class="text-purple-600">DJL</strong> 中，<code class="bg-gray-100 px-2 py-1 rounded">NDArray</code> 是一个核心组件，代表了 <strong>N 维数组</strong>（N-Dimensional Array）。它是存储和操作数据的基本单位，就像 NumPy 的 <code class="bg-gray-100 px-2 py-1 rounded">ndarray</code> 或 TensorFlow 和 PyTorch 的张量（Tensor）。<code class="bg-gray-100 px-2 py-1 rounded">NDArray</code> 通常用于存储模型的输入、输出以及中间计算结果，比如图片、文本、矩阵等数据。
                </p>
                
                <div class="flex justify-center my-8">
                    <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1734161748875-764c3779-895f-4ada-8b1b-2c13d10c9263.png" 
                         alt="NDArray示意图" 
                         class="rounded-lg shadow-lg border border-gray-200 max-w-full h-auto">
                </div>
            </div>
            
            <div class="grid md:grid-cols-2 gap-8">
                <div class="bg-white rounded-xl shadow-md p-8">
                    <h3 class="text-xl font-semibold mb-4 flex items-center">
                        <i class="fas fa-question-circle text-purple-600 mr-2"></i>
                        为什么叫NDArray？
                    </h3>
                    <p class="text-gray-700">
                        <strong>N</strong> 表示维度，比如一张图片可以看成 3 维数组（高、宽、通道），一段文本嵌入可以是 2 维数组（句子长度 × 嵌入维度）。
                    </p>
                </div>
                
                <div class="bg-white rounded-xl shadow-md p-8">
                    <h3 class="text-xl font-semibold mb-4 flex items-center">
                        <i class="fas fa-bolt text-purple-600 mr-2"></i>
                        它的作用是什么？
                    </h3>
                    <p class="text-gray-700">
                        你可以把它想象成一个超强的表格，能存储任意大小的数据，并且支持快速的数学运算，比如加减乘除、矩阵运算等。
                    </p>
                </div>
                
                <div class="bg-white rounded-xl shadow-md p-8 md:col-span-2">
                    <h3 class="text-xl font-semibold mb-4 flex items-center">
                        <i class="fas fa-star text-purple-600 mr-2"></i>
                        和普通数组的区别？
                    </h3>
                    <ul class="list-disc pl-6 space-y-2 text-gray-700">
                        <li>支持 GPU 加速，计算更快</li>
                        <li>可以无缝对接深度学习模型，用于模型训练或推理</li>
                        <li>提供许多高效的数学和线性代数操作，开发者不需要手写复杂逻辑</li>
                    </ul>
                </div>
            </div>
        </section>

        <!-- Usage Section -->
        <section class="mb-16">
            <div class="flex items-center mb-8">
                <div class="w-8 h-8 bg-purple-600 rounded-full flex items-center justify-center text-white mr-4">
                    <i class="fas fa-tasks"></i>
                </div>
                <h2 class="text-3xl font-bold">NDArray的常见用途</h2>
            </div>
            
            <div class="grid md:grid-cols-3 gap-6">
                <div class="feature-card bg-white rounded-xl shadow-md p-6 transition-all duration-300">
                    <div class="text-purple-600 mb-4">
                        <i class="fas fa-database text-3xl"></i>
                    </div>
                    <h3 class="text-xl font-semibold mb-3">存储输入输出数据</h3>
                    <p class="text-gray-600">
                        存储图片、文本或时间序列等数据，作为模型处理的输入和输出。
                    </p>
                </div>
                
                <div class="feature-card bg-white rounded-xl shadow-md p-6 transition-all duration-300">
                    <div class="text-purple-600 mb-4">
                        <i class="fas fa-calculator text-3xl"></i>
                    </div>
                    <h3 class="text-xl font-semibold mb-3">进行数值运算</h3>
                    <p class="text-gray-600">
                        计算损失函数、更新权重参数等深度学习中的核心数学运算。
                    </p>
                </div>
                
                <div class="feature-card bg-white rounded-xl shadow-md p-6 transition-all duration-300">
                    <div class="text-purple-600 mb-4">
                        <i class="fas fa-layer-group text-3xl"></i>
                    </div>
                    <h3 class="text-xl font-semibold mb-3">中间计算结果</h3>
                    <p class="text-gray-600">
                        保存神经网络各层的输出结果，如卷积层、池化层的特征图。
                    </p>
                </div>
            </div>
        </section>

        <!-- Visualization Section -->
        <section class="mb-16">
            <div class="flex items-center mb-8">
                <div class="w-8 h-8 bg-purple-600 rounded-full flex items-center justify-center text-white mr-4">
                    <i class="fas fa-project-diagram"></i>
                </div>
                <h2 class="text-3xl font-bold">NDArray核心概念关系</h2>
            </div>
            
            <div class="bg-white rounded-xl shadow-md p-6">
                <div class="mermaid">
                    graph TD
                        A[NDArray] --> B[创建方式]
                        A --> C[数据类型]
                        A --> D[维度操作]
                        A --> E[数学运算]
                        A --> F[内存管理]
                        
                        B --> B1[从Java数组创建]
                        B --> B2[从文件加载]
                        B --> B3[随机初始化]
                        
                        C --> C1[float32]
                        C --> C2[int32]
                        C --> C3[boolean]
                        
                        D --> D1[reshape]
                        D --> D2[transpose]
                        D --> D3[broadcast]
                        
                        E --> E1[加减乘除]
                        E --> E2[矩阵乘法]
                        E --> E3[归约运算]
                        
                        F --> F1[NDManager]
                        F --> F2[自动释放]
                        F --> F3[内存池]
                        
                        style A fill:#7c3aed,color:white,stroke-width:0px
                        style B fill:#8b5cf6,color:white,stroke-width:0px
                        style C fill:#8b5cf6,color:white,stroke-width:0px
                        style D fill:#8b5cf6,color:white,stroke-width:0px
                        style E fill:#8b5cf6,color:white,stroke-width:0px
                        style F fill:#8b5cf6,color:white,stroke-width:0px
                </div>
            </div>
        </section>

        <!-- Operations Section -->
        <section class="mb-16">
            <div class="flex items-center mb-8">
                <div class="w-8 h-8 bg-purple-600 rounded-full flex items-center justify-center text-white mr-4">
                    <i class="fas fa-code"></i>
                </div>
                <h2 class="text-3xl font-bold">NDArray的常用操作</h2>
            </div>
            
            <div class="space-y-8">
                <!-- Operation 1 -->
                <div class="bg-white rounded-xl shadow-md overflow-hidden">
                    <div class="p-6">
                        <h3 class="text-xl font-semibold mb-4 flex items-center">
                            <span class="bg-purple-100 text-purple-800 w-8 h-8 rounded-full flex items-center justify-center mr-3">1</span>
                            创建NDArray
                        </h3>
                        <div class="code-block p-4 rounded-lg mb-4">
                            <pre><code class="text-sm">NDManager manager = NDManager.newBaseManager();
NDArray array = manager.create(new float[]{1, 2, 3, 4, 5});
System.out.println(array);  // 输出: [1, 2, 3, 4, 5]</code></pre>
                        </div>
                        <p class="text-gray-600">
                            使用<code class="bg-gray-100 px-1 py-0.5 rounded">NDManager</code>创建NDArray实例，这是管理NDArray生命周期的核心类。
                        </p>
                    </div>
                </div>
                
                <!-- Operation 2 -->
                <div class="bg-white rounded-xl shadow-md overflow-hidden">
                    <div class="p-6">
                        <h3 class="text-xl font-semibold mb-4 flex items-center">
                            <span class="bg-purple-100 text-purple-800 w-8 h-8 rounded-full flex items-center justify-center mr-3">2</span>
                            基础数学运算
                        </h3>
                        <div class="code-block p-4 rounded-lg mb-4">
                            <pre><code class="text-sm">NDArray array1 = manager.create(new float[]{1, 2, 3});
NDArray array2 = manager.create(new float[]{4, 5, 6});
NDArray sum = array1.add(array2);  // 加法
System.out.println(sum);  // 输出: [5, 7, 9]</code></pre>
                        </div>
                        <p class="text-gray-600">
                            NDArray支持各种数学运算，包括加、减、乘、除等，运算会自动广播到每个元素。
                        </p>
                    </div>
                </div>
                
                <!-- Operation 3 -->
                <div class="bg-white rounded-xl shadow-md overflow-hidden">
                    <div class="p-6">
                        <h3 class="text-xl font-semibold mb-4 flex items-center">
                            <span class="bg-purple-100 text-purple-800 w-8 h-8 rounded-full flex items-center justify-center mr-3">3</span>
                            维度操作
                        </h3>
                        <div class="code-block p-4 rounded-lg mb-4">
                            <pre><code class="text-sm">NDArray reshaped = array.reshape(1, 5);  // 将1D转为2D
System.out.println(reshaped.getShape());  // 输出: (1, 5)</code></pre>
                        </div>
                        <p class="text-gray-600">
                            <code class="bg-gray-100 px-1 py-0.5 rounded">reshape</code>操作可以改变数组的形状而不改变数据内容，是神经网络中常用的操作。
                        </p>
                    </div>
                </div>
                
                <!-- Operation 4 -->
                <div class="bg-white rounded-xl shadow-md overflow-hidden">
                    <div class="p-6">
                        <h3 class="text-xl font-semibold mb-4 flex items-center">
                            <span class="bg-purple-100 text-purple-800 w-8 h-8 rounded-full flex items-center justify-center mr-3">4</span>
                            从图像创建NDArray
                        </h3>
                        <div class="code-block p-4 rounded-lg mb-4">
                            <pre><code class="text-sm">Image img = ImageFactory.getInstance().fromFile(new File("image.jpg"));
NDArray imgArray = img.toNDArray(manager);
System.out.println(imgArray.getShape());  // 输出图片张量的形状</code></pre>
                        </div>
                        <p class="text-gray-600">
                            DJL提供了便捷的API将图像转换为NDArray，便于计算机视觉任务的处理。
                        </p>
                    </div>
                </div>
                
                <!-- Operation 5 -->
                <div class="bg-white rounded-xl shadow-md overflow-hidden">
                    <div class="p-6">
                        <h3 class="text-xl font-semibold mb-4 flex items-center">
                            <span class="bg-purple-100 text-purple-800 w-8 h-8 rounded-full flex items-center justify-center mr-3">5</span>
                            矩阵乘法
                        </h3>
                        <div class="code-block p-4 rounded-lg mb-4">
                            <pre><code class="text-sm">NDArray matrix1 = manager.create(new float[][]{{1, 2}, {3, 4}});
NDArray matrix2 = manager.create(new float[][]{{5, 6}, {7, 8}});
NDArray product = matrix1.matMul(matrix2);  // 矩阵乘法
System.out.println(product);</code></pre>
                        </div>
                        <p class="text-gray-600">
                            矩阵乘法是神经网络中最核心的运算之一，<code class="bg-gray-100 px-1 py-0.5 rounded">matMul</code>方法提供了高效的实现。
                        </p>
                    </div>
                </div>
            </div>
        </section>

        <!-- Example Section -->
        <section>
            <div class="flex items-center mb-8">
                <div class="w-8 h-8 bg-purple-600 rounded-full flex items-center justify-center text-white mr-4">
                    <i class="fas fa-laptop-code"></i>
                </div>
                <h2 class="text-3xl font-bold">实战示例：矩阵加法和图片归一化</h2>
            </div>
            
            <div class="bg-white rounded-xl shadow-md overflow-hidden">
                <div class="p-6">
                    <div class="code-block p-4 rounded-lg">
                        <pre><code class="text-sm">import ai.djl.ndarray.NDArray;
import ai.djl.ndarray.NDManager;
import ai.djl.modality.cv.Image;
import ai.djl.modality.cv.ImageFactory;

import java.io.File;

public class NDArrayDemo {
    public static void main(String[] args) throws Exception {
        // 创建NDManager，用于管理NDArray生命周期
        NDManager manager = NDManager.newBaseManager();

        // 1. 创建两个矩阵并进行加法
        NDArray matrix1 = manager.create(new float[][]{{1, 2}, {3, 4}});
        NDArray matrix2 = manager.create(new float[][]{{5, 6}, {7, 8}});
        NDArray sum = matrix1.add(matrix2);
        System.out.println("矩阵加法结果:\n" + sum);

        // 2. 从文件加载图片并归一化
        Image img = ImageFactory.getInstance().fromFile(new File("path/to/image.jpg"));
        NDArray imgArray = img.toNDArray(manager).div(255);  // 归一化处理
        System.out.println("图片张量形状: " + imgArray.getShape());
    }
}</code></pre>
                    </div>
                    
                    <div class="mt-6 p-6 bg-purple-50 rounded-lg">
                        <h4 class="font-semibold text-lg mb-3 flex items-center">
                            <i class="fas fa-info-circle text-purple-600 mr-2"></i>
                            代码解析
                        </h4>
                        <ul class="list-disc pl-6 space-y-2 text-gray-700">
                            <li><code class="bg-gray-100 px-1 py-0.5 rounded">NDManager</code> 负责管理NDArray的生命周期，避免内存泄漏</li>
                            <li>矩阵加法演示了NDArray的基本运算能力</li>
                            <li>图片加载后通过<code class="bg-gray-100 px-1 py-0.5 rounded">div(255)</code>实现了归一化处理，这是图像处理的常见预处理步骤</li>
                            <li>DJL的<code class="bg-gray-100 px-1 py-0.5 rounded">ImageFactory</code>提供了便捷的图像加载和转换功能</li>
                        </ul>
                    </div>
                </div>
            </div>
        </section>
    </main>

    <!-- Footer -->
    <footer class="bg-gray-900 text-gray-300 py-12">
        <div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
            <div class="text-center">
                <h3 class="text-xl font-semibold text-white mb-2">技术小馆</h3>
                <p class="mb-6">探索深度学习与Java的无限可能</p>
                <div class="flex justify-center space-x-6">
                    <a href="http://www.yuque.com/jtostring" class="footer-link hover:text-white transition-colors duration-200">
                        <i class="fas fa-globe mr-1"></i> 技术小馆地址
                    </a>
                </div>
            </div>
        </div>
    </footer>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
        
        // 平滑滚动
        document.querySelectorAll('a[href^="#"]').forEach(anchor => {
            anchor.addEventListener('click', function (e) {
                e.preventDefault();
                document.querySelector(this.getAttribute('href')).scrollIntoView({
                    behavior: 'smooth'
                });
            });
        });
    </script>
</body>
</html>